package com.request.service.impl.shop.sj;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.request.common.constants.RedisConstant;
import com.request.common.enums.RechargeTypeEnum;
import com.request.common.enums.SjErrorCodeEnum;
import com.request.common.utils.HttpUtils;
import com.request.entity.PhoneOrderWaitCheck;
import com.request.service.QueryOrderProcessor;
import com.request.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Description:
 * Create DateTime: 2020/5/22 10:54
 *
 * 

 */
@Slf4j
@Service
public class SjQueryOrderProcessor implements QueryOrderProcessor {

    @Resource
    private RedisService redisService;

    @Resource
    private ThreadPoolExecutor handlerOrderExecutor;

    @Override
    public void sendRequest(PhoneOrderWaitCheck orderWaitCheck) {
        handlerOrderExecutor.execute(() -> executeWaitOrderQuery(orderWaitCheck));
    }

    /**
     * 执行待查询订单查询
     */
    private void executeWaitOrderQuery(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        Map<String, Object> params = new HashMap<>();
        String result = null;
        try {
            String querySite = phoneOrderWaitCheck.getQuerySite();
            String platformOrderNo = phoneOrderWaitCheck.getPlatformOrderNo();
            String appId = phoneOrderWaitCheck.getAppId();

            StringBuilder sb = new StringBuilder(appId);
            sb.append(platformOrderNo).append(phoneOrderWaitCheck.getAppKey());

            String signStr = SecureUtil.md5(sb.toString());

            params.put("merchantId", appId);
            params.put("tradeNoThird", platformOrderNo);
            params.put("signstr", signStr);

            result = sendRequestForWaitOrder(querySite, params);
            log.info("【SJ】【查单】结果:{}", result);
            JSONObject jsonObject = JSONObject.parseObject(result);

            Integer code = jsonObject.getInteger("code");

            SjErrorCodeEnum sjErrorCodeEnum = SjErrorCodeEnum.getByCode(code);

            switch (sjErrorCodeEnum) {
                case SUCCESS:
                    String tradeNo = jsonObject.getJSONObject("body").getString("tradeNo");
                    phoneOrderWaitCheck.setStatus(1);
                    phoneOrderWaitCheck.setOrderSn(tradeNo);
                    break;
                case ORDER_PAYING:
                    saveWaitOrderQueryForProcessing(phoneOrderWaitCheck);
                    break;
                default:
                    phoneOrderWaitCheck.setStatus(0);
                    saveWaitOrderQueryForSuccess(phoneOrderWaitCheck);
                    break;
            }
        } catch (Exception e) {
            saveWaitOrderQueryForProcessing(phoneOrderWaitCheck);
            log.error("【SJ】【超时检查】请求商户出现异常，待检查订单信息为：{}, 参数为：{}, 响应结果为:{}, 详情为：{}",
                    phoneOrderWaitCheck, params.toString(), result, e);
        }
    }

    /**
     * 放入失败队列(废弃)
     * 原因：该处理状态在hf通道中弃用
     */
    @Deprecated
    private void saveWaitOrderQueryForFailed(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        redisService.lPush(RedisConstant.PUSH_ORDER_WAIT_CHECK_FAILED, JSON.toJSONString(phoneOrderWaitCheck));
    }

    /**
     * 放入成功队列
     */
    private void saveWaitOrderQueryForSuccess(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        redisService.lPush(RedisConstant.PUSH_ORDER_WAIT_CHECK_SUCCESS, JSON.toJSONString(phoneOrderWaitCheck));
    }

    private String sendRequestForWaitOrder(String url, Map<String, Object> params) {
        return HttpUtils.doGet(url, params);
    }

    /**
     * 放入处理中队列
     */
    private void saveWaitOrderQueryForProcessing(PhoneOrderWaitCheck phoneOrderWaitCheck) {
        if (!RechargeTypeEnum.SLOW.getCode().equals(phoneOrderWaitCheck.getRechargeType())) {
            redisService.lPush(RedisConstant.PUSH_ORDER_WAIT_CHECK_PROCESSING, JSON.toJSONString(phoneOrderWaitCheck));
        }
    }
}
